部署
(一)配置站点域名
Keycloak 强烈建议用独立子域名 auth.ordinis.dev,不要和主站(www.ordinis.dev)共用同一个域名与路径。
1. Cloudflare DNS
新增记录:
auth→ A → 你的服务器 IP → Proxied(橙云)

2. 部署 Nginx 站点
Nginx 进行转发: auth.ordinis.dev → 127.0.0.1:8081
创建站点配置:
sudo tee /etc/nginx/sites-available/auth.ordinis.dev > /dev/null <<'EOF'
server {
listen 80;
server_name auth.ordinis.dev;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name auth.ordinis.dev;
ssl_certificate /etc/nginx/ssl/ordinis.dev/origin-cert.pem;
ssl_certificate_key /etc/nginx/ssl/ordinis.dev/origin-key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Keycloak 对反代头比较敏感,建议加上:
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
}
}
EOF
启用并重载:
sudo ln -sf /etc/nginx/sites-available/auth.ordinis.dev /etc/nginx/sites-enabled/auth.ordinis.dev
sudo nginx -t && sudo systemctl reload nginx
(二)安装 Docker
更新系统与安装依赖
sudo apt update && sudo apt -y upgrade
sudo apt -y install ca-certificates curl gnupg ufw
安装 Docker 与 Compose 插件
# 安装 Docker 官方源
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
确认 Docker / Compose 可用
docker --version
docker compose version
docker info | head
确认服务状态
sudo systemctl status docker --no-pager
清理掉“半装不装”的系统包(如果有)
只在你确实装过系统版
containerd/docker.io的情况下做;你现在报错说明系统可能有containerd依赖链,但不一定已安装。可以先检查:dpkg -l | egrep 'docker\.io|containerd($| )|runc'
- 如果看到
docker.io或containerd(注意不是containerd.io),建议移除系统版,保持官方版:sudo apt remove -y docker.io containerd runc sudo apt autoremove -y这不会影响你已经装好的
docker-ce/containerd.io,反而避免未来冲突。
你已经装的是 Docker 官方源,后续请用:
docker-cedocker-ce-clicontainerd.iodocker-compose-plugin
不要再碰:
docker.iocontainerd(系统版)
(三) 部署 Postgres + Keycloak
在服务器创建目录:
mkdir -p ~/keycloak && cd ~/keycloak
写入 docker-compose.yml,注意修改密 码
services:
db:
image: postgres:16
container_name: keycloak_db
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: [此处为密码]
volumes:
- kc_pgdata:/var/lib/postgresql/data
networks:
- kcnet
keycloak:
image: quay.io/keycloak/keycloak:26.0
container_name: keycloak
restart: unless-stopped
command: start --proxy-headers=xforwarded --http-enabled=true --hostname=auth.ordinis.dev
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://db:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: [此处为密码,注意和上面的 POSTGRES_PASSWORD 一样]
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: [此处为密码]
KC_PROXY: edge
KC_PROXY_HEADERS: xforwarded
KC_HOSTNAME: auth.ordinis.dev
KC_HOSTNAME_STRICT: "true"
KC_HOSTNAME_STRICT_HTTPS: "true"
depends_on:
- db
ports:
- "127.0.0.1:8081:8080"
networks:
- kcnet
volumes:
kc_pgdata:
networks:
kcnet:
建议你把密码在 YAML 里用引号包起来,避免 YAML 解析边界问题:
POSTGRES_PASSWORD: "..."
启动:
docker compose up -d
docker compose ps
本机验证 Keycloak 是否起来:(注意启动后要等 3 分钟)
curl -I http://127.0.0.1:8081
返回内容应为:
HTTP/1.1 302 Found
Location: http://auth.ordinis.dev:8081/admin/
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
浏览器打开:https://auth.ordinis.dev,用你在 compose 里设置的:admin / change_me_admin_password 登录 Keycloak 管理台:

注:如果要修改密码/重新部署 → 删除旧数据库卷并重启
因为 Postgres 初始化密码只在首次创建数据卷时生效。你改 compose 但不删卷,数据库里仍是旧密码,会继续失败。
cd ~/keycloak docker compose down docker volume rm keycloak_kc_pgdata docker compose up -d显示日志
docker compose logs -n 50 keycloak
docker compose logs -n 50 db如果你已经在库里有数据(通常你现在还没有),那就要进入 Postgres 容器里改密码:
docker exec -it keycloak_db psql -U keycloak -d keycloak然后在 psql 里执行(把新密码换成你要的):
ALTER USER keycloak WITH PASSWORD '你的新密码'; \q并确保
KC_DB_PASSWORD也改成同一个新密码,然后:docker compose restart keycloak
(四)新建安全账户
网页上登录后有一条警告:
You are logged in as a temporary admin user. To harden security, create a permanent admin account and delete the temporary one.
含义是你现在登录使用的是 启动时通过环境变量创建的临时管理员:
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=...
这个账号 仅用于 首次初始化 / 紧急访问, 不受 Keycloak 内部用户策略(MFA、角色审计、禁用等)完整管理,同时 通常会被扫描器重点尝试爆破(用户名固定)
Keycloak 的安全模型要求你 把“真正的管理员”放到 Realm 的用户体系里,而不是依赖这个 bootstrap 账号。
1. 创建新账号
在 Keycloak Admin Console 中:
-
进入
masterRealm -
左侧 Users → Create user
注意:你现在创建的这个用户 = Keycloak 的“身份与权限管理用户”,并非是 业务用户(End User)

-
创建一个新用户,例如:
- Username:
ordinis-admin - Email:你的管理员邮箱
- required user actions: 不选
- 创建好之后为:
- 
- Username:
-
设置密码
Credentials→Set password- Temporary:OFF
-
授权
-
Users→heihe→Role mapping此时应该只有一个 权限

-
点击
Assign role- 左上角把筛选切到Filter by clients- 全选 -Assign这里是该用户对 client 层面的管理能力,比如创建/删除 client,

-
点击
Assign role- 左上角把筛选切到Filter by clients- 全选 -Assign这里是该用户对 Realm 层面的管理能力,比如创建/删除 Realm

-
-
多重身份验证(可选)
-
Account → Security → 开启 OTP

-
手动进入控制台
此时,进入
Application界面,会只能看到这个控制台
这个控制台是“账号私人控制台”,不是 “整个用户系统的管理界面”
其 URL 是
https://auth.ordinis.dev/realms/master/account/需要我们手动登录
https://auth.ordinis.dev/admin/之后这里才会显示出两个控制台,其中上面一个才是整个用户系统的控制台

注:在 Create User 时,有要选择 user actions。其含义为这个用户“第一次登录时,必须被强制完成哪些动作”。它不是权限,也不是功能开关,而是登录流程控制。对于管理员而言,应该一个都不要选。

- Configure OTP(配置一次性验证码):第一次登录必须绑定 MFA(Google Authenticator 等)
- Update Password:第一次登录必须改密码
-
Verify Email:必须点邮箱里的验证链接才能继续,如果你还没配置 SMTP,会直接卡死
-
Webauthn Register / Passwordless:强制注册硬件密钥 / 无密码登录
-
Update Profile / Verify Profile:强制用户补充个人信息
2. 删除临时 admin
确认新账号可用后:
-
在
docker-compose.yml中 删除:KEYCLOAK_ADMIN KEYCLOAK_ADMIN_PASSWORD -
重启 Keycloak:
docker compose restart keycloak -
删除或禁用
admin在 Admin Console(master realm)里:
选择
masterrealm →Users→ 找到用户名admin→ 删除admin账号
此时,我们就无法再使用 临时的 admin 账号登录了
额外检查:你有没有把“永久管理员”建在对的 Realm?
注意:
Keycloak Admin Console 的管理权限通常在 master realm(尤其是你要管理整个 Keycloak 实例)。
你新建的永久管理员应该满足:
- 在 master realm 下创建
- Role mapping 里有:
realm-management→realm-admin
否则你可能误以为有永久管理员,但实际上只有 admin 真能管系统。